#include "stdafx.h"
#include "WindowManager.h"

namespace quicks {

	WindowManager::WindowManager() {
		mutex = CreateMutex( 
			NULL,              // default security attributes
			FALSE,             // initially not owned
			NULL);             // unnamed mutex

		//TODO: ASSERT(mutex != NULL);
	}

	WindowManager::~WindowManager() {
		CloseHandle(mutex);
	}

	const std::vector<WindowManager::WindowDesc>* WindowManager::GetWindows() {
		WaitForSingleObject(mutex, INFINITE); // this locking doesn't work
		windows.clear();
		EnumWindows( (WNDENUMPROC) WindowManager::ProcessWindow, (LPARAM) this );
		if (windows.size() > 1) {
			WindowDesc wd;
			HWND hWndFront = GetForegroundWindow();
			// is the current window in the list?
			std::vector<WindowManager::WindowDesc>::iterator cur = windows.begin();
			for ( ; cur != windows.end(); cur++) {
				if (cur->handle == hWndFront) break;
			}
			if (cur != windows.end()) {
				std::vector<WindowManager::WindowDesc>::iterator fst = windows.begin();
				while (fst->handle != hWndFront) {
					wd = *fst;
					windows.erase(fst);
					windows.push_back(wd);
					fst = windows.begin();
				}
				fst = windows.begin();
				wd = *fst;
				windows.erase(fst);
				windows.push_back(wd);
			}
		}
		ReleaseMutex(mutex);
		return (const std::vector<WindowManager::WindowDesc>*) &windows;
	}

	void WindowManager::SwitchTo(WindowDesc window) {
		SwitchToThisWindow(window.handle, true);
	}

	BOOL CALLBACK WindowManager::ProcessWindow(HWND hWnd, LPARAM lParam) {
		WindowManager* wm = (WindowManager*) lParam;
		BOOL bRetVal = TRUE;
		LPWSTR lpsz;
		int nTitleLength;

		// tried: IsWindow(hWnd) - didn't filter out any
		// tried: IsWindowEnabled(hWnd) - filtered out threads (OLE etc)
		if (::GetParent(hWnd) != NULL)  // owned - won't be in taskbar
		{
			//TRACE0("Owned window\n");
		}
		else if (::GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_TOOLWINDOW)
		{
			//TRACE0("Window is a tool window\n");
		}
		else if (!::IsWindowVisible(hWnd))
		{
			//TRACE0("Window not visible\n");
		}
		else if ((nTitleLength = ::GetWindowTextLength(hWnd)) == 0)
		{
			// no title!
			//TRACE0("Window has no title\n");
		}
		else
		{
			nTitleLength++;
			lpsz = new TCHAR[nTitleLength];
			if (::GetWindowText(hWnd, lpsz, nTitleLength) == 0)
			{
				// must be an error!
				bRetVal = FALSE;
			}
			else if (_tcsicmp(lpsz, _T("Windows Task Manager")) != 0)
			{
				// everything looks good, add to the list
				WindowManager::WindowDesc wd;
				wd.handle = hWnd;
				wd.name = std::wstring(lpsz);
				wm->windows.push_back(wd);
			}
			delete lpsz;
		}
		return bRetVal;
	}
}